In [1]:
def deco(func):
def inner():
print('running inner()')
return inner
In [2]:
@deco
def target():
print('running target()')
In [3]:
target()
In [12]:
registry= []
def register(func):
print('running register(%s)' % func)
registry.append(func)
return func
@register
def f1():
print('running f1()')
@register
def f2():
print('running f2()')
def f3():
print('running f3()')
In [13]:
def main():
print('running main()')
print('registry ->', registry)
f1()
f2()
f3()
In [14]:
main()
In [15]:
promos = []
def promotion(promo_func):
promos.append(promo_func)
return promo_func
@promotion
def fidelity(order):
"""5% discount for customers with 1000 or more fidelity points"""
return order.total() * .05 if order.customer.fidelity >= 1000 else 0
@promotion
def bulk_item(order):
"""10% discount for each LineItem with 20 or more units"""
discount = 0
for item in order.cart:
if item.quantity >= 20:
discount += item.total() * .1
return discount
@promotion
def large_order(order):
"""7% discount for oders with 10 or more distinct items"""
distinct_items = {item.product for item in order.cart}
if len(distinct_items) >= 10:
return order.total() * .07
return 0
def best_promo(order):
"""Select best discount available"""
return max(promo(order) for promo in promos)
In [16]:
def f1(a):
print(a)
print(b)
In [17]:
f1(3)
In [18]:
b=6
f1(3)
In [19]:
def f2(a):
print(a)
print(b)
b=9
In [20]:
f2(3)
In [21]:
def f3(a):
global b
print(a)
print(b)
b=9
In [22]:
f3(3)
In [24]:
class Averager():
def __init__(self):
self.series = []
def __call__(self, new_value):
self.series.append(new_value)
total = sum(self.series)
return total/len(self.series)
In [25]:
avg = Averager()
In [26]:
avg(10)
Out[26]:
In [27]:
avg(11)
Out[27]:
In [28]:
avg(12)
Out[28]:
In [30]:
def make_averager():
series = []
def averager(new_value):
series.append(new_value)
total = sum(series)
return total/len(series)
return averager
In [31]:
avg = make_averager()
In [32]:
avg(10)
Out[32]:
In [33]:
avg(11)
Out[33]:
In [34]:
avg(12)
Out[34]:
In [35]:
avg.__code__.co_varnames
Out[35]:
In [36]:
avg.__code__.co_freevars
Out[36]:
In [37]:
avg.__closure__
Out[37]:
In [38]:
avg.__closure__[0].cell_contents
Out[38]:
In [41]:
def make_averager():
count = 0
total = 0
def averager(new_value):
nonlocal count, total
count += 1
total += new_value
return total / count
return averager
In [42]:
avg = make_averager()
avg(10)
Out[42]:
In [46]:
import time
def clock(func):
def clocked(*args):
t0 = time.perf_counter()
result = func(*args)
elapsed = time.perf_counter() - t0
name = func.__name__
arg_str = ', '.join(repr(arg) for arg in args)
print('[%0.8fs] %s(%s) -> %r' % (elapsed, name, arg_str, result))
return result
return clocked
In [47]:
@clock
def snooze(seconds):
time.sleep(seconds)
@clock
def factorial(n):
return 1 if n < 2 else n*factorial(n-1)
In [49]:
print('*' * 40, 'Calling snooze(.123)')
snooze(.123)
print('*' * 40, 'Calling factorial(6)')
print('6! =', factorial(6))
In [51]:
factorial.__name__
Out[51]:
In [52]:
import functools
In [53]:
def clock(func):
@functools.wraps(func)
def clocked(*args, **kwargs):
t0 = time.time()
result = func(*args, **kwargs)
elapsed = time.time() - t0
name = func.__name__
arg_lst = []
if args:
arg_lst.append(', '.join(repr(arg) for arg in args))
if kwargs:
pairs = ['%s=%r' % (k, w) for k, w in sorted(kwargs.items())]
arg_lst.append(', '.join(pairs))
arg_str = ', '.join(arg_lst)
print('[%0.8fs] %s(%s) -> %r' % (elapsed, name, arg_str, result))
return result
return clocked
In [56]:
@clock
def snooze(seconds):
time.sleep(seconds)
@clock
def factorial(n):
return 1 if n < 2 else n*factorial(n-1)
In [57]:
print('*' * 40, 'Calling snooze(.123)')
snooze(.123)
print('*' * 40, 'Calling factorial(6)')
print('6! =', factorial(6))
In [58]:
factorial.__name__
Out[58]:
In [7]:
from clockdeco import clock
In [4]:
@clock
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-2) + fibonacci(n-1)
In [5]:
print(fibonacci(6))
In [8]:
import functools
In [9]:
@functools.lru_cache()
@clock
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-2) + fibonacci(n-1)
In [10]:
print(fibonacci(6))
In [14]:
import html
def htmlize(obj):
content = html.escape(repr(obj))
return '<pre>{}</pre>'.format(content)
In [19]:
htmlize({1, 2, 3})
Out[19]:
In [20]:
htmlize(abs)
Out[20]:
In [22]:
htmlize('Heimlich & co.\n- a game')
Out[22]:
In [24]:
htmlize(42)
Out[24]:
In [25]:
print(htmlize(['alpha', 66, {3, 2, 1}]))
In [27]:
from functools import singledispatch
from collections import abc
import numbers
import html
In [28]:
@singledispatch
def htmlize(obj):
content = html.escape(repr(obj))
return '<pre>{}</pre>'.format(content)
@htmlize.register(str)
def _(text):
content = html.escape(text).replace('\n', '<br>\n')
return '<p>{0}</p>'.format(content)
@htmlize.register(numbers.Integral)
def _(n):
return '<pre>{0} (0x{0:x})</pre>'.format(n)
@htmlize.register(tuple)
@htmlize.register(abc.MutableSequence)
def _(seq):
inner = '</li>\n<li>'.join(htmlize(item) for item in seq)
return '<ul>\n<li>' + inner + '</li>\n</ul>'
In [29]:
htmlize({1, 2, 3})
Out[29]:
In [30]:
htmlize(abs)
Out[30]:
In [31]:
htmlize('Heimlich & co.\n- a game')
Out[31]:
In [32]:
htmlize(42)
Out[32]:
In [33]:
print(htmlize(['alpha', 66, {3, 2, 1}]))
In [37]:
registry = []
def register(func):
print('running register(%s)' % func)
registry.append(func)
return func
@register
def f1():
print('running f1()')
In [38]:
print('running main()')
print('registry ->', registry)
f1()
In [39]:
registry = set()
def register(active=True):
def decorate(func):
print('running register(active=%s)->decorate(%s)' % (active, func))
if active:
registry.add(func)
else:
registry.discard(func)
return func
return decorate
@register(active=False)
def f1():
print('running f1()')
@register()
def f2():
print('running f2()')
def f3():
print('running f3()')
In [40]:
f1()
In [43]:
repr(registry)
Out[43]:
In [44]:
from registration_param import *
In [45]:
registry
Out[45]:
In [46]:
register()(f3)
Out[46]:
In [47]:
registry
Out[47]:
In [48]:
register(active=False)(f2)
Out[48]:
In [49]:
registry
Out[49]:
In [52]:
import time
DEFAULT_FMT = '[{elapsed:0.8f}s] {name}({args}) -> {result}'
def clock(fmt=DEFAULT_FMT):
def decorate(func):
def clocked(*_args):
t0 = time.time()
_result = func(*_args)
elapsed = time.time() - t0
name = func.__name__
args = ', '.join(repr(arg) for arg in _args)
result = repr(_result)
print(fmt.format(**locals()))
return result
return clocked
return decorate
In [54]:
@clock()
def snooze(seconds):
time.sleep(seconds)
for i in range(3):
snooze(.123)
In [60]:
import time
from clockdeco_param import clock
In [61]:
@clock('{name}: {elapsed}s')
def snooze(seconds):
time.sleep(seconds)
for i in range(3):
snooze(.123)
In [62]:
@clock('{name}({args}) dt={elapsed:0.3f}s')
def snooze(seconds):
time.sleep(seconds)
for i in range(3):
snooze(.123)
In [ ]: